﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Windows.ApplicationModel.Resources.Core;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
using System.Collections.Specialized;
using Windows.Storage;
using Windows.ApplicationModel;
using Windows.Data.Json;
using System.Globalization;
using System.Threading.Tasks;
using System.IO;
using System.Net.Http;
using Windows.Networking.BackgroundTransfer;
using Windows.UI.ApplicationSettings;

// The data model defined by this file serves as a representative example of a strongly-typed
// model that supports notification when members are added, removed, or modified.  The property
// names chosen coincide with data bindings in the standard t templates.
//
// Applications may use this model as a starting point and build on it, or discard it entirely and
// replace it with something appropriate to their needs.

namespace SoTaySinhVienUIT.Data {
    /// <summary>
    /// Base class for <see cref="SampleDataItem"/> and <see cref="SampleDataGroup"/> that
    /// defines properties common to both.
    /// </summary>
    [Windows.Foundation.Metadata.WebHostHidden]
    public abstract class SampleDataCommon : SoTaySinhVienUIT.Common.BindableBase {
        public static Uri _baseUri = new Uri("ms-appx:///");

        public SampleDataCommon(String uniqueId, String title, String subtitle, String imagePath, String description) {
            this._uniqueId = uniqueId;
            this._title = title;
            this._subtitle = subtitle;
            this._description = description;
            this._imagePath = imagePath;
        }

        private string _uniqueId = string.Empty;
        public string UniqueId {
            get { return this._uniqueId; }
            set { this.SetProperty(ref this._uniqueId, value); }
        }

        private string _title = string.Empty;
        public string Title {
            get { return this._title; }
            set { this.SetProperty(ref this._title, value); }
        }

        private string _subtitle = string.Empty;
        public string Subtitle {
            get { return this._subtitle; }
            set { this.SetProperty(ref this._subtitle, value); }
        }

        private string _description = string.Empty;
        public string Description {
            get { return this._description; }
            set { this.SetProperty(ref this._description, value); }
        }

        private ImageSource _image = null;
        private String _imagePath = null;
        public ImageSource Image {
            get {
                if (this._image == null && this._imagePath != null) {
                    this._image = new BitmapImage(new Uri(SampleDataCommon._baseUri, this._imagePath));
                }
                return this._image;
            }

            set {
                this._imagePath = null;
                this.SetProperty(ref this._image, value);
            }
        }

        public void SetImage(String path) {
            this._image = null;
            this._imagePath = path;
            this.OnPropertyChanged("Image");
        }

        public override string ToString() {
            return this.Title;
        }

        private String _note = String.Empty;
        public String Note {
            get { return _note; }
            set {
                this.SetProperty(ref this._note, value);
            }
        }

        private bool _favorite = false;
        public bool Favorite {
            get { return _favorite; }
            set {
                if (!this._favorite.Equals(value)) {
                }
                this.SetProperty(ref this._favorite, value);
            }
        }

        private String _icon = String.Empty;
        public String Icon {
            get { return _icon; }
            set { this.SetProperty(ref this._icon, value); }
        }

    }

    /// <summary>
    /// Generic t data model.
    /// </summary>
    public class SampleDataItem : SampleDataCommon {
        public SampleDataItem(String uniqueId, String title, String subtitle, String imagePath, String description, String content, SampleDataGroup group, SampleDataTopic topic)
            : base(uniqueId, title, subtitle, imagePath, description) {
            this._content = content;
            this._group = group;
            this._topic = topic;

            this.Icon = "\uE132";
        }

        protected string _content = string.Empty;
        public string Content {
            get { return this._content; }
            set { this.SetProperty(ref this._content, value); }
        }

        protected SampleDataGroup _group;
        public SampleDataGroup Group {
            get { return this._group; }
            set { this.SetProperty(ref this._group, value); }
        }

        protected SampleDataTopic _topic;
        public SampleDataTopic Topic {
            get { return this._topic; }
            set { this.SetProperty(ref this._topic, value); }
        }

        private ImageSource _imageContent = null;

        private String _imageContentPath = null;
        public ImageSource ImageContent {
            get {
                if (this._imageContent == null && this._imageContentPath != null) {
                    this._imageContent = new BitmapImage(new Uri(new Uri("http://khabeouit.orgfree.com/data_uitstudenthandbook/"), this._imageContentPath));
                }
                return this._imageContent;
            }

            set {
                this._imageContentPath = null;
                this.SetProperty(ref this._imageContent, value);
            }
        }

        public void SetImageContent(String path) {
            this._imageContent = null;
            this._imageContentPath = path;
            this.OnPropertyChanged("ImageContent");
        }

        public bool HasContented {
            get {
                if (_content.Substring(_content.Length - 3, 3).Equals("rtf")) {
                    return true;
                }
                return false;
            }
        }
    }

    public class SampleDataTopic : SampleDataItem {

        public SampleDataTopic(String uniqueId, String title, String subtitle, String imagePath, String description, String content, SampleDataGroup group)
            : base(uniqueId, title, subtitle, imagePath, description, content, group, null) {
            this._content = content;
            this._group = group;
            this.Icon = "\uE1D3";
        }


        private void ItemsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) {
            // Provides a subset of the full items collection to bind to from a GroupedItemsPage
            // for two reasons: GridView will not virtualize large items collections, and it
            // improves the user experience when browsing through stsvs with large numbers of
            // items.
            //
            // A maximum of 12 items are displayed because it results in filled grid columns
            // whether there are 1, 2, 3, 4, or 6 rows displayed

            switch (e.Action) {
                case NotifyCollectionChangedAction.Add:
                    if (e.NewStartingIndex < 12) {
                        TopItems.Insert(e.NewStartingIndex, Items[e.NewStartingIndex]);
                        if (TopItems.Count > 12) {
                            TopItems.RemoveAt(12);
                        }
                    }
                    break;
                case NotifyCollectionChangedAction.Move:
                    if (e.OldStartingIndex < 12 && e.NewStartingIndex < 12) {
                        TopItems.Move(e.OldStartingIndex, e.NewStartingIndex);
                    }
                    else if (e.OldStartingIndex < 12) {
                        TopItems.RemoveAt(e.OldStartingIndex);
                        TopItems.Add(Items[11]);
                    }
                    else if (e.NewStartingIndex < 12) {
                        TopItems.Insert(e.NewStartingIndex, Items[e.NewStartingIndex]);
                        TopItems.RemoveAt(12);
                    }
                    break;
                case NotifyCollectionChangedAction.Remove:
                    if (e.OldStartingIndex < 12) {
                        TopItems.RemoveAt(e.OldStartingIndex);
                        if (Items.Count >= 12) {
                            TopItems.Add(Items[11]);
                        }
                    }
                    break;
                case NotifyCollectionChangedAction.Replace:
                    if (e.OldStartingIndex < 12) {
                        TopItems[e.OldStartingIndex] = Items[e.OldStartingIndex];
                    }
                    break;
                case NotifyCollectionChangedAction.Reset:
                    TopItems.Clear();
                    while (TopItems.Count < Items.Count && TopItems.Count < 12) {
                        TopItems.Add(Items[TopItems.Count]);
                    }
                    break;
            }
        }

        private ObservableCollection<SampleDataItem> _items = new ObservableCollection<SampleDataItem>();
        public ObservableCollection<SampleDataItem> Items {
            get { return this._items; }
        }

        private ObservableCollection<SampleDataItem> _topItem = new ObservableCollection<SampleDataItem>();
        public ObservableCollection<SampleDataItem> TopItems {
            get { return this._topItem; }
        }
        
    }

    /// <summary>
    /// Generic group data model.
    /// </summary>
    public class SampleDataGroup : SampleDataCommon {
        public SampleDataGroup(String uniqueId, String title, String subtitle, String imagePath, String description)
            : base(uniqueId, title, subtitle, imagePath, description) {
            Items.CollectionChanged += ItemsCollectionChanged;
        }

        private void ItemsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) {
            // Provides a subset of the full items collection to bind to from a GroupedItemsPage
            // for two reasons: GridView will not virtualize large items collections, and it
            // improves the user experience when browsing through stsvs with large numbers of
            // items.
            //
            // A maximum of 12 items are displayed because it results in filled grid columns
            // whether there are 1, 2, 3, 4, or 6 rows displayed

            switch (e.Action) {
                case NotifyCollectionChangedAction.Add:
                    if (e.NewStartingIndex < 12) {
                        TopItems.Insert(e.NewStartingIndex, Items[e.NewStartingIndex]);
                        if (TopItems.Count > 12) {
                            TopItems.RemoveAt(12);
                        }
                    }
                    break;
                case NotifyCollectionChangedAction.Move:
                    if (e.OldStartingIndex < 12 && e.NewStartingIndex < 12) {
                        TopItems.Move(e.OldStartingIndex, e.NewStartingIndex);
                    }
                    else if (e.OldStartingIndex < 12) {
                        TopItems.RemoveAt(e.OldStartingIndex);
                        TopItems.Add(Items[11]);
                    }
                    else if (e.NewStartingIndex < 12) {
                        TopItems.Insert(e.NewStartingIndex, Items[e.NewStartingIndex]);
                        TopItems.RemoveAt(12);
                    }
                    break;
                case NotifyCollectionChangedAction.Remove:
                    if (e.OldStartingIndex < 12) {
                        TopItems.RemoveAt(e.OldStartingIndex);
                        if (Items.Count >= 12) {
                            TopItems.Add(Items[11]);
                        }
                    }
                    break;
                case NotifyCollectionChangedAction.Replace:
                    if (e.OldStartingIndex < 12) {
                        TopItems[e.OldStartingIndex] = Items[e.OldStartingIndex];
                    }
                    break;
                case NotifyCollectionChangedAction.Reset:
                    TopItems.Clear();
                    while (TopItems.Count < Items.Count && TopItems.Count < 12) {
                        TopItems.Add(Items[TopItems.Count]);
                    }
                    break;
            }
        }

        private ObservableCollection<SampleDataItem> _items = new ObservableCollection<SampleDataItem>();
        public ObservableCollection<SampleDataItem> Items {
            get { return this._items; }
        }

        private ObservableCollection<SampleDataItem> _topItem = new ObservableCollection<SampleDataItem>();
        public ObservableCollection<SampleDataItem> TopItems {
            get { return this._topItem; }
        }

    }

    public class FavoriteTopicGroup : SampleDataGroup {
        public FavoriteTopicGroup(String uniqueId, String title, String subtitle, String imagePath, String description)
            : base(uniqueId, title, subtitle, imagePath, description) {
        }
    }

    public class FavoriteItemGroup : SampleDataGroup {
        public FavoriteItemGroup(String uniqueId, String title, String subtitle, String imagePath, String description)
            : base(uniqueId, title, subtitle, imagePath, description) {
        }

    }

    /// <summary>
    /// Creates a collection of stsvs and items with hard-coded content.
    /// 
    /// SampleDataSource initializes with placeholder data rather than live production
    /// data so that sample data is provided at both design-time and run-time.
    /// </summary>
    public sealed class SampleDataSource {
        private static SampleDataSource _sampleDataSource = new SampleDataSource();

        private ObservableCollection<SampleDataGroup> _allGroups = new ObservableCollection<SampleDataGroup>();
        public ObservableCollection<SampleDataGroup> AllGroups {
            get { return this._allGroups; }
        }

        public static IEnumerable<SampleDataGroup> GetGroups(string uniqueId) {
            if (!uniqueId.Equals("AllGroups")) throw new ArgumentException("Only 'AllGroups' is supported as a collection of stsvs");

            return _sampleDataSource.AllGroups;
        }

        public static IEnumerable<SampleDataTopic> GetTopics(string uniqueId) {
            if (!uniqueId.Equals("AllTopics")) throw new ArgumentException("Only 'AllTopics' is supported as a collection of stsvs");

            return _sampleDataSource.AllGroups.SelectMany(t => t.Items) as IEnumerable<SampleDataTopic>;
        }

        public static SampleDataGroup GetGroup(string uniqueId) {
            // Simple linear search is acceptable for small data sets
            var matches = _sampleDataSource.AllGroups.Where((group) => group.UniqueId.Equals(uniqueId));
            if (matches.Count() == 1) return matches.First();
            return null;
        }

        public static SampleDataTopic GetItem(string uniqueId) {
            // Simple linear search is acceptable for small data sets
            var matches = _sampleDataSource.AllGroups.Where(t => !t.UniqueId.Contains("FAVORITE")).SelectMany(group => group.Items).Where((item) => item.UniqueId.Equals(uniqueId));
            if (matches.Count() == 1) return matches.First() as SampleDataTopic;
            return null;
        }

        public static List<String> FavoriteSave = null;
        public static Dictionary<String, String> NoteSave = null;

        public static DateTime Updated;

        public static async Task CheckLocalDataStorageRtf(String filename) {

            StorageFolder folder = ApplicationData.Current.LocalFolder;
            folder = await folder.CreateFolderAsync("data", CreationCollisionOption.OpenIfExists);
            folder = await folder.CreateFolderAsync("rtf", CreationCollisionOption.OpenIfExists);

            bool isFound = true;
            try {
                var file = await folder.GetFileAsync(filename);
            }
            catch (FileNotFoundException exp) {
                isFound = false;
            }
            if (!isFound) {
                // Copy from app package
                var filelocal = await Package.Current.InstalledLocation.GetFileAsync("Data\\rtf\\" + filename);
                if (filelocal != null) {
                    await filelocal.CopyAsync(folder, filename, NameCollisionOption.ReplaceExisting);
                }
            }
        }

        // Check if local.txt not existed on local storage
        public static async Task CheckLocalDataStorage(String filename) {

            StorageFolder folder = ApplicationData.Current.LocalFolder;
            folder = await folder.CreateFolderAsync("data", CreationCollisionOption.OpenIfExists);
            bool isFound = true;
            try {
                var file = await folder.GetFileAsync(filename);
            }
            catch (FileNotFoundException exp) {
                isFound = false;
            }
            if (!isFound) {
                // Copy from app package
                var filelocal = await Package.Current.InstalledLocation.GetFileAsync("Data\\" + filename);
                if (filelocal != null) {
                    await filelocal.CopyAsync(folder, filename, NameCollisionOption.ReplaceExisting);
                }
            }

        }

        // Read from local txt

        public static async Task LoadLocalData(String filename) {
            StorageFolder folder = ApplicationData.Current.LocalFolder;
            folder = await folder.CreateFolderAsync("data", CreationCollisionOption.OpenIfExists);
            var file = await folder.GetFileAsync(filename);

            var result = await FileIO.ReadTextAsync(file);

            var stsvs = JsonArray.Parse(result);

            var destGroupsList = _sampleDataSource._allGroups;

            foreach (var ttitem in stsvs) {

                var stsv = ttitem.GetObject();

                foreach (var key in stsv.Keys) {

                    IJsonValue val;

                    var provider = CultureInfo.InvariantCulture;
                    var format = "d/M/yyyy h:m tt";

                    if (!stsv.TryGetValue(key, out val))
                        continue;

                    switch (key) {
                        case "updated":
                            var s = val.GetString();
                            Updated = DateTime.ParseExact(val.GetString(), format, provider);
                            break;
                        case "groups":

                            var groups = val.GetArray();
                            foreach (var g in groups) {
                                var group = new SampleDataGroup(String.Empty, String.Empty, String.Empty, String.Empty, String.Empty);
                                var obj = g.GetObject();
                                foreach (var k in obj.Keys) {
                                    IJsonValue val1;
                                    if (!obj.TryGetValue(k, out val1))
                                        continue;
                                    switch (k) {
                                        case "id":
                                            group.UniqueId = val1.GetString();
                                            break;
                                        case "title":
                                            group.Title = val1.GetString();
                                            break;
                                        case "subtitle":
                                            group.Subtitle = val1.GetString();
                                            break;
                                        case "image":
                                            group.SetImage(val1.GetString());
                                            break;
                                        case "description":
                                            group.Description = val1.GetString();
                                            break;
                                        case "icon":
                                            group.Icon = val1.GetString();
                                            break;
                                        case "topics":

                                            var topics = val1.GetArray();
                                            foreach (var t in topics) {
                                                var topic = new SampleDataTopic(String.Empty, String.Empty, String.Empty, String.Empty, String.Empty, String.Empty, null);
                                                var obj1 = t.GetObject();
                                                foreach (var k1 in obj1.Keys) {
                                                    IJsonValue val11;
                                                    if (!obj1.TryGetValue(k1, out val11))
                                                        continue;
                                                    switch (k1) {
                                                        case "id":
                                                            topic.UniqueId = val11.GetString();
                                                            break;
                                                        case "title":
                                                            topic.Title = val11.GetString();
                                                            break;
                                                        case "subtitle":
                                                            topic.Subtitle = val11.GetString();
                                                            break;
                                                        case "content":
                                                            topic.Content = val11.GetString();
                                                            if (topic.Content.Substring(topic.Content.Length - 3, 3).Equals("png") || topic.Content.Substring(topic.Content.Length - 3, 3).Equals("jpg")) {
                                                                topic.SetImageContent("images/" + topic.Content);
                                                            }
                                                            break;
                                                        case "image":
                                                            topic.SetImage(val11.GetString());
                                                            break;
                                                        case "description":
                                                            topic.Description = val11.GetString();
                                                            break;
                                                        case "icon":
                                                            topic.Icon = val11.GetString();
                                                            break;
                                                        case "items":
                                                            var items = val11.GetArray();
                                                            foreach (var it in items) {
                                                                var item = new SampleDataItem(String.Empty, String.Empty, String.Empty, String.Empty, String.Empty, String.Empty, null, null);
                                                                var obj11 = it.GetObject();
                                                                foreach (var k11 in obj11.Keys) {
                                                                    IJsonValue val111;
                                                                    if (!obj11.TryGetValue(k11, out val111))
                                                                        continue;
                                                                    switch (k11) {
                                                                        case "id":
                                                                            item.UniqueId = val111.GetString();
                                                                            break;
                                                                        case "title":
                                                                            item.Title = val111.GetString();
                                                                            break;
                                                                        case "subtitle":
                                                                            item.Subtitle = val111.GetString();
                                                                            break;
                                                                        case "image":
                                                                            item.SetImage(val111.GetString());
                                                                            break;
                                                                        case "description":
                                                                            item.Description = val111.GetString();
                                                                            break;
                                                                        case "icon":
                                                                            item.Icon = val111.GetString();
                                                                            break;
                                                                        case "content":
                                                                            item.Content = val111.GetString();                                                                          
                                                                            if (item.Content.Substring(item.Content.Length - 3, 3).Equals("png") || item.Content.Substring(item.Content.Length - 3, 3).Equals("jpg")) {
                                                                                item.SetImageContent("images/" + item.Content);
                                                                            }
                                                                            break;
                                                                    }
                                                                }
                                                                item.Group = group;
                                                                item.Topic = topic;
                                                                topic.Items.Add(item);
                                                            }
                                                            break;
                                                    }
                                                }
                                                topic.Group = group;
                                                topic.Topic = null;
                                                group.Items.Add(topic);
                                            }
                                            break;
                                    }
                                }
                                destGroupsList.Add(group);
                            }
                            break;
                    }

                }
            }
        }

        public static async Task<bool> CheckUpdate() {
            var client = new HttpClient();
            client.MaxResponseContentBufferSize = 1024 * 1024; // Read up to 1 MB of data
            var response = await client.GetAsync(new Uri("http://khabeouit.orgfree.com/data_uitstudenthandbook/update.txt"));
            var result = await response.Content.ReadAsStringAsync();


            var provider = CultureInfo.InvariantCulture;
            var format = "d/M/yyyy h:m tt";

            var newer = DateTime.ParseExact(result, format, provider);

            if (newer <= Updated) {
                return false;
            }

            return true;
        }

        public static async Task<bool> UpdateFromWeb(String filename) {

            if (await CheckUpdate()) {

                var client = new HttpClient();
                client.MaxResponseContentBufferSize = 1024 * 1024; // Read up to 1 MB of data
                var response = await client.GetAsync(new Uri("http://khabeouit.orgfree.com/data_uitstudenthandbook/studenthandbook.txt"));
                var result = await response.Content.ReadAsStringAsync();

                await CheckLocalDataStorage(filename);

                StorageFolder folder = ApplicationData.Current.LocalFolder;
                folder = await folder.CreateFolderAsync("data", CreationCollisionOption.OpenIfExists);

                var file = await folder.GetFileAsync(filename);

                await FileIO.WriteTextAsync(file, result, Windows.Storage.Streams.UnicodeEncoding.Utf8);
                return true;
            }
            return false;
        }

        public static async Task LoadData() {

            if (_sampleDataSource.AllGroups.Count == 0) {

                var loader = new Windows.ApplicationModel.Resources.ResourceLoader("MainPage");

                var favoritetopicgroup = new FavoriteTopicGroup("FAVORITE_GROUP", loader.GetString("FavoriteTitle"), String.Empty, String.Empty, String.Empty);

                var favoriteitemgroup = new FavoriteItemGroup("FAVORITE_GROUP_ITEM", loader.GetString("FavoriteTitleItem"), String.Empty, String.Empty, String.Empty);

                var notegroup = new FavoriteItemGroup("FAVORITE_GROUP_ITEM_NOTE", loader.GetString("NoteTitle"), String.Empty, String.Empty, String.Empty);

                _sampleDataSource.AllGroups.Add(favoritetopicgroup);
                _sampleDataSource.AllGroups.Add(favoriteitemgroup);
                _sampleDataSource.AllGroups.Add(notegroup);

                await CheckLocalDataStorage("local.txt");
                await LoadLocalData("local.txt");

                // Load from file
                await LoadFavoriteLocal("fav.txt");
                // Load SaveData
                await LoadNoteLocal("note.txt");

                var collection = _sampleDataSource.AllGroups
                    .Where(g => !g.UniqueId.Contains("FAVORITE"));

                //Favorite
                foreach (SampleDataTopic topic in collection.SelectMany(t => t.Items)) {

                    if (SampleDataSource.FavoriteSave.Contains(topic.UniqueId)) {
                        topic.Favorite = true;
                    }

                    if (SampleDataSource.NoteSave.Keys.Contains(topic.UniqueId)) {
                        topic.Note = SampleDataSource.NoteSave.Where(k => k.Key.Equals(topic.UniqueId)).ElementAt(0).Value;
                    }
                }

                foreach (SampleDataItem item in collection.SelectMany(t => t.Items).SelectMany(i => (i as SampleDataTopic).Items)) {

                    if (SampleDataSource.FavoriteSave.Contains(item.UniqueId)) {
                        item.Favorite = true;
                    }

                    if (SampleDataSource.NoteSave.Keys.Contains(item.UniqueId)) {
                        item.Note = SampleDataSource.NoteSave.Where(k => k.Key.Equals(item.UniqueId)).ElementAt(0).Value;
                    }
                }
            }
        }

        public static async Task LoadFavoriteLocal(String filename) {
            await CheckLocalDataStorage(filename);

            StorageFolder folder = ApplicationData.Current.LocalFolder;
            folder = await folder.CreateFolderAsync("data", CreationCollisionOption.OpenIfExists);
            var file = await folder.GetFileAsync(filename);

            var result = await FileIO.ReadTextAsync(file);

            FavoriteSave = result.Split(new char[] { ',' }).ToList<String>();
        }

        public static async Task LoadNoteLocal(String filename) {
            await CheckLocalDataStorage(filename);

            NoteSave = new Dictionary<string, string>();

            StorageFolder folder = ApplicationData.Current.LocalFolder;
            folder = await folder.CreateFolderAsync("data", CreationCollisionOption.OpenIfExists);
            var file = await folder.GetFileAsync(filename);

            var result = await FileIO.ReadTextAsync(file);

            var pairs = result.Split(new char[] { ',' });

            foreach (var pair in pairs) {
                if (!String.IsNullOrEmpty(pair)) {
                    var item = pair.Split(new char[] { '|' });
                    NoteSave.Add(item[0], item[1]);
                }
            }

        }
        public SampleDataSource() {
        }

        public static async Task SaveFavoriteLocal(String filename) {
            await CheckLocalDataStorage(filename);

            StorageFolder folder = ApplicationData.Current.LocalFolder;
            folder = await folder.CreateFolderAsync("data", CreationCollisionOption.OpenIfExists);

            var file = await folder.GetFileAsync(filename);

            String text = String.Empty;

            foreach (var fav in SampleDataSource.GetGroup("FAVORITE_GROUP").Items) {
                text += fav.UniqueId + ",";
            }

            foreach (var fav in SampleDataSource.GetGroup("FAVORITE_GROUP_ITEM").Items) {
                text += fav.UniqueId + ",";
            }

            text = text.Remove(text.Length - 1);

            await FileIO.WriteTextAsync(file, text, Windows.Storage.Streams.UnicodeEncoding.Utf8);
        }

        public static async Task SaveNoteLocal(String filename) {
            await CheckLocalDataStorage(filename);

            StorageFolder folder = ApplicationData.Current.LocalFolder;
            folder = await folder.CreateFolderAsync("data", CreationCollisionOption.OpenIfExists);

            var file = await folder.GetFileAsync(filename);

            String text = String.Empty;

            foreach (var note in SampleDataSource.GetGroup("FAVORITE_GROUP_ITEM_NOTE").Items) {

                String value = note.Note;

                text += note.UniqueId + "|" + value + ",";
            }
            text = text.Remove(text.Length - 1);

            await FileIO.WriteTextAsync(file, text, Windows.Storage.Streams.UnicodeEncoding.Utf8);
        }

        public static void ClearGroups() {
            _sampleDataSource._allGroups.Clear();
        }

        public static void AddSettingsCommands(SettingsPaneCommandsRequestedEventArgs args) {
            args.Request.ApplicationCommands.Clear();

            SettingsCommand privacyPref = new SettingsCommand("privacyPref", "Privacy Policy", async (uiCommand) => {

                await Windows.System.Launcher.LaunchUriAsync(new Uri("https://www.facebook.com/notes/kha-b%C3%A9o-nguy%E1%BB%85n/privacy-policy/162458647253343"));

            });

            args.Request.ApplicationCommands.Add(privacyPref);

        }
    }
}
